﻿using System;
using System.Collections.Generic;
using ShortcutToolbox.Core;
using ShortcutToolbox.Model;

namespace ShortcutToolbox.Controller
{
    class MainController : IShortcutToolboxController
    {
        public IReadOnlyList<IPlugin> Plugins { get; protected set; } = new List<IPlugin>();

        public event EventHandler OnStart;
        public event EventHandler OnStop;
        public event EventHandler<LanguageChangedEventArgs> OnLanguageChanged;
        public event EventHandler<BooleanValueChangedEventArgs> OnAutoStartupChanged;
        public event EventHandler<BooleanValueChangedEventArgs> OnCheckUpdateOnStartChanged;
        public event EventHandler<ToolBoxEventArgs> OnShowLogForm;
        public event EventHandler<ToolBoxEventArgs> OnShowAboutForm;
        public event EventHandler<ToolBoxEventArgs> OnCheckUpdate;
        public event EventHandler<ToolBoxEventArgs> OnShowConfigurationForm;

        public MainController()
        {
            if (!string.IsNullOrEmpty(Configuration.Current.Language))
            {
                Language lang = I18N.GetLang(Configuration.Current.Language);
                if (lang != null)
                    I18N.SetLang(lang);
            }

            I18N.Changed += onLanguageChanged;
            AutoStartup.Changed += onAutoStartupChanged;

        }

        public void Start()
        {
            IList<IPlugin> plugins = Core.Plugins.GetPlugins();
            List<IPlugin> list = new List<IPlugin>(plugins.Count);
            list.AddRange(plugins);
            Plugins = list;
            foreach (IPlugin plugin in list)
            {
                try
                {
                    plugin.Init(this);
                    plugin.StatusChanged += onPluginStatusChanged;
                }
                catch(Exception ex)
                {
                    Logging.LogUsefulException(ex);
                }
            }
            OnStart?.Invoke(this, new EventArgs());
        }

        public void Stop()
        {
            foreach (IPlugin plugin in Plugins)
            {
                try
                {
                    plugin.StatusChanged -= onPluginStatusChanged;
                    plugin.Uninit();
                }
                catch (Exception ex)
                {
                    Logging.LogUsefulException(ex);
                }
            }
            OnStop?.Invoke(this, new EventArgs());
        }

        public bool SetLanguage(string name)
        {
            Language lang = I18N.GetLang(name);
            if (lang != null)
            {
                Configuration.Current.Language = Convert.ToString(lang["name"]);
                Configuration.Current.Save();
                I18N.SetLang(lang);
                return true;
            }
            return false;
        }

        public bool SetAutoStart(bool autoStart)
        {
            return AutoStartup.Set(autoStart);
        }

        public bool SetCheckUpdateOnStart(bool enable)
        {
            Configuration.Current.CheckUpdateOnStart = enable;
            Configuration.Current.Save();
            OnCheckUpdateOnStartChanged?.Invoke(this, new BooleanValueChangedEventArgs(enable));
            return true;
        }

        public bool CheckUpdate(object userState)
        {
            if (OnCheckUpdate != null)
            {
                OnCheckUpdate.Invoke(this, new ToolBoxEventArgs(userState));
                return true;
            }
            return false;
        }

        public bool ShowConfigurationForm(object userState)
        {
            if (OnShowConfigurationForm != null)
            {
                OnShowConfigurationForm.Invoke(this, new ToolBoxEventArgs(userState));
                return true;
            }
            return false;
        }

        public bool ShowAboutForm(object userState)
        {
            if (OnShowAboutForm != null)
            {
                OnShowAboutForm.Invoke(this, new ToolBoxEventArgs(userState));
                return true;
            }
            return false;
        }

        public bool ShowLogForm(object userState)
        {
            if (OnShowLogForm != null)
            {
                OnShowLogForm.Invoke(this, new ToolBoxEventArgs(userState));
                return true;
            }
            return false;
        }

        public Delegate[] GetEventInvocationList(string eventName)
        {
            switch (eventName)
            {
                case "OnStart":
                    return OnStart.GetInvocationList();
                case "OnStop":
                    return OnStop.GetInvocationList();
                case "OnLanguageChanged":
                    return OnLanguageChanged.GetInvocationList();
                case "OnAutoStartupChanged":
                    return OnAutoStartupChanged.GetInvocationList();
                case "OnCheckUpdateOnBootChanged":
                    return OnCheckUpdateOnStartChanged.GetInvocationList();
                case "OnShowAboutForm":
                    return OnShowAboutForm.GetInvocationList();
                case "OnCheckUpdate":
                    return OnCheckUpdate.GetInvocationList();
            }
            return null;
        }

        public bool ClearEventInvocations(string eventName)
        {
            switch(eventName)
            {
                case "OnStart":
                    OnStart = null;
                    return true;
                case "OnStop":
                    OnStop = null;
                    return true;
                case "OnLanguageChanged":
                    OnLanguageChanged = null;
                    return true;
                case "OnAutoStartupChanged":
                    OnAutoStartupChanged = null;
                    return true;
                case "OnCheckUpdateOnBootChanged":
                    OnCheckUpdateOnStartChanged = null;
                    return true;
                case "OnShowAboutForm":
                    OnShowAboutForm = null;
                    return true;
                case "OnCheckUpdate":
                    OnCheckUpdate = null;
                    return true;
            }
            return false;
        }

        private void onLanguageChanged(object sender, LanguageChangedEventArgs e)
        {
            OnLanguageChanged?.Invoke(this, e);
        }

        private void onAutoStartupChanged(object sender, BooleanValueChangedEventArgs e)
        {
            OnAutoStartupChanged?.Invoke(this, e);
        }

        private void onPluginStatusChanged(object sender, EventArgs e)
        {
            
        }
    }


}
